//---------------------------------------------------------------------------

#ifndef EAH
#define EAH

#define Malloc(type,n) (type *)malloc((n)*sizeof(type))

#ifdef CLOCKS_PER_SEC
 static const double CLOCK_TICKS_PER_SECOND = (double)CLOCKS_PER_SEC;
 #elif defined(CLK_TCK)
 static const double CLOCK_TICKS_PER_SECOND = (double)CLK_TCK;
 #else
 static const double CLOCK_TICKS_PER_SECOND = 1000000.0;
 #endif

#define TRUE      1
#define FALSE     0

#define MAXINT    100007

#define	MAXV      2000		/* maximum number of vertices */
#define MAXDEGREE 2000		/* maximum outdegree of a vertex */

typedef struct sEdge{
	int v;				/* neighboring vertex */
	float weight;			/* edge weight */
} edge;

typedef struct sGraph{
	edge edges[MAXV+1][MAXDEGREE];	/* adjacency info */
	int degree[MAXV+1];		/* outdegree of each vertex */
	int nvertices;			/* number of vertices in the graph */
	int nedges;			/* number of edges in the graph */
} graph;


typedef struct Table {
  int inCurrentNode;
  int inNumberNodes;
  int *ptPointer;
} GroupTable;


typedef struct Adjacent {
  int inNodeName;
  float inWeight;
} AdjacentNode;

typedef struct Node {
  int inNodeName;
  int inNumberAdjacents;
   float x,y;
  AdjacentNode *ptPointer;
   bool flag;
  int Depth;
} GraphNode;

typedef struct Colunm {
  int inForest;
  int inTree;
  int inIndex;
  int inDeph;
} PositionColunm;

typedef struct NodeStructure {
  int inNodeName;
  int inNumberColunms;
  PositionColunm **stColunms;
} PositionMatrix;

typedef struct TreeStructure {
  int inTreeName;
  int inNumberNodes;
  int *stNodes;
  int *stDephs;
} Tree;

typedef struct ForestStructure {
 int inForestName;
 int inNumberTrees;
 double fpFitness;
 Tree **stTrees;
} Forest;


void insert_edge(graph *g, int x, int y, bool directed, float w);
void process_vertex(int v);
void process_edge(int x, int y);

void LoadAdjacentTable();
int *GetAdjacentNodes(int inNodeParam);
int GetNumberAdjacentNodes(int inNodeParam);
int AdjacentBinarySearch (GraphNode *stNodesParam, int inSearchParam, int inLastParam);
void ReleaseAdjacentTable();
int read_graph(graph *g, char *filename, bool directed);

void LoadPositionMatrix(GraphNode *graph);
void LoadPI();
void SetGenitor(int inForestParam, int inGenitorParam);
PositionColunm *GetPosition(int inNodeParam, int inForestParam);
void AddPosition(int inNodeParam, int inForestParam, int inTreeParam, int inIndexParam, int inDephParam);
int PositionBinarySearch (PositionMatrix *stMatrixParam, int inSearchParam, int inLastParam);
int ColunmBinarySearch (PositionMatrix *stMatrixParam, int inIndexParam, int inSearchParam, int inLastParam);
void ReleasePositionMatrix();
void print_tree( Tree *stTreeParam, char *chParam, int inStart, int inEnd );
void print_forest( Forest * stForest);

Forest *LoadForest(GraphNode *tree);
Forest *CreateForest(int inNumberTreesParam, int inForestNameParam);
Tree *GetTree(Forest *stForestParam, int inTreeParam);
void SetTree(Forest *stForestParam, Tree *stTreeParam, int inTreeParam);
void ReleaseForest(Forest *stForestParam);
void  ReleaseAdjacentTable();
int GetNumber(int inLow, int inHigh);
double GetNumberReal(double inLow, double inHigh);

void EARun(int inNumberGenerationsParam, int inNumberPopulationParam, int inRestrictionParam, int NumExecParam);

#endif
